#include <stdio.h>

#if defined(UNIX) || defined(__unix__)
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#elif defined(WIN32)
#include <windows.h>
#endif

#include "fndefer.h"

//----------------------------------------------

void test()
{
    FILE *fp = fopen("test.txt", "r");
    if (nullptr == fp)
        return;

    // 注册 defer,
    auto defer_func = [&]()
    { fclose(fp); };

    Defer __Defer__Release(defer_func);

    // 开始使用 fp,
    if (1)
    {
        return;
    }
}

//----------------------------------------------

void test_fd()
{
#if defined(UNIX) || defined(__unix__)
    // #include <unistd.h>
    // #include <sys/types.h>
    // #include <sys/stat.h>
    // #include <fcntl.h>

    int fd = open("test.txt", O_RDWR | O_CREAT, 0664);
    if (-1 == fd)
    {
        perror("open failed!");
    }

    // 注册 defer,
    auto defer_func = [&]()
    {
        printf("fd = %d will close.\n", fd);
        close(fd);
    };

    Defer __Defer__Release(defer_func);

    // 开始使用 fd,
    if (1)
    {
        printf("fd = %d, do something ...\n", fd);
        return;
    }

#elif defined(WIN32)
    TEST_LOG("======= win32 thread exit =======");
#endif
    return;
}

//----------------------------------------------

class Test
{
public:
    void f(int i)
    {
        printf("f:%d %p\n", i, this);
    }
};

int main001(int argc, char const *argv[])
{
    Test t;
    printf("test:%p\n", &t);

    auto defer_func1 = [&]()
    { t.f(1); };
    auto defer_func2 = [&]()
    { t.f(2); };
    auto defer_func3 = [&]()
    { t.f(3); };

    Defer d1(defer_func1);
    Defer d2(defer_func2);
    Defer d3(defer_func3);

    // test:0x7ffe9783c4cf
    // f:1 0x7ffe9783c4cf
    // f:2 0x7ffe9783c4cf
    // f:3 0x7ffe9783c4cf

    return 0;
}

int main002(int argc, char const *argv[])
{
    Test t;
    printf("test:%p\n", &t);

    defer(t.f(1)); // Defer defer2(__Defer__,__COUNTER__) ([&](){t.f(1);});
    defer(t.f(2)); // Defer defer2(__Defer__,__COUNTER__) ([&](){t.f(2);});
    defer(t.f(3)); // Defer defer2(__Defer__,__COUNTER__) ([&](){t.f(3);});

    // ==>
    // defer(t.f(1));
    // Defer defer2(__Defer__,__COUNTER__) ([&](){t.f(4);});
    // Defer defer1(__Defer__, 224)([&](){t.f(4);});
    Defer __Defer__224([&]()
                       { t.f(4); });

    return 0;
}

int main(int argc, char const *argv[])
{
    // main001(argc, argv);
    // main002(argc, argv);
    test_fd();
    return 0;
}
